package robocup.testing;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Arc2D;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import java.util.LinkedList;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

import robocup.component.SConf;
import robocup.component.geometry.Circle;
import robocup.component.geometry.CircleSegment;
import robocup.component.geometry.LineSegment;
import robocup.component.geometry.StraightLine;
import robocup.component.geometry.Vektor;
import robocup.component.geometry.analysers.PossibleBallsAfterDirectedAcc;
import robocup.component.geometry.analysers.PossibleBallsAfterPoweredAcc;
import robocup.component.geometry.analysers.ReachableArea;
import robocup.component.situations.ScoreSituation.ShotEvaluatorResults;
import robocup.component.situations.ScoreSituation.ShotEvaluatorResults.SHOT_VALUE;
import robocup.component.util.Randoms;
import robocup.component.worldobjects.Ball;
import robocup.component.worldobjects.Player;

/**
 * @author Thomas Karbe
 * 
 * This is an abstract class to test graphical methods on classes (e.g. from
 * geometry package). To use it, extend this class and implement the three
 * abstract methods.
 * 
 * By creating an object of this class, a window opens that displays two buttons
 * and a coordinate system. The paintSituation methods includes the objects that
 * should be drawn into this coordinate system. The methods nextSituation and
 * nextCycle are called when the cooresponding buttons are used.
 * 
 * This class contains many methods to draw objects from the geometry-package
 * and to get random values in a given range.
 * 
 */
public abstract class GraphicalTestFrame
    extends JFrame {
  
  private final Color transparentBlue= new Color(0,0,255,100);  
  private final Color transparentBrown= new Color(150,105,0,100);   
  private final Color transparentRed= new Color(255,0,0,100);  
  private final Color transparentGreen= new Color(0,255,0,100);

  private static final double SCALE_STANDARD     = 50;
  private static final int    X_OFFSET           = 40;
  private static final int    Y_OFFSET           = 20;
  private double              minX;
  private double              maxX;
  private double              minY;
  private double              maxY;
  private double              scalefact;
  private Dimension           dimension          = new Dimension(850, 600);
  private Vektor              center             = new Vektor();

  private Line2D.Double       shapeLine          = new Line2D.Double();
  private Arc2D.Double        shapeArc           = new Arc2D.Double();
  private Rectangle2D.Double  shapeRect          = new Rectangle2D.Double();

  private Color               actColor           = Color.BLACK;
  private LineSegment         dummyLineSegment   = LineSegment
                                                     .getDummyInstance();
  // private StraightLine dummyStraightLine= StraightLine.getDummyInstance();
  private Circle              dummyCircle        = Circle.getDummyInstance();
  private CircleSegment       dummyCircleSegment = CircleSegment
                                                     .getDummyInstance();
  private Vektor              dummyVektor        = Vektor.getDummyInstance();
  private Vektor              dummyVektor2       = Vektor.getDummyInstance();

  protected Randoms            rand              = Randoms.getInstance();
  private boolean             fresh              = true;

  /**
   * Creates a new test frame with standard scale fact, standard window size and
   * center (0,0)
   */
  public GraphicalTestFrame() {

    super();
    this.addWindowListener(new WindowClosingAdapter(true));
    scalefact = SCALE_STANDARD;
    setContentPane(new ContentPanel());
    setPreferredSize(dimension);
    pack();
    setVisible(true);
  }

  /**
   * Creates a new test frame with standard scale fact, given window size and
   * center (0,0)
   * 
   * @param d
   *          the size of the window
   */
  public GraphicalTestFrame(
      Dimension d) {

    super();
    this.addWindowListener(new WindowClosingAdapter(true));
    scalefact = SCALE_STANDARD;
    dimension.width = d.width;
    dimension.height = d.height;
    setPreferredSize(dimension);
    setContentPane(new ContentPanel());
    pack();
    setVisible(true);
  }

  /**
   * Creates a new test frame with standard scale fact, standard window size and
   * given center
   * 
   * @param center
   *          the center of the window
   */
  public GraphicalTestFrame(
      Vektor center) {

    super();
    this.addWindowListener(new WindowClosingAdapter(true));
    scalefact = SCALE_STANDARD;
    this.center.copy(center);
    setContentPane(new ContentPanel());
    setPreferredSize(dimension);
    pack();
    setVisible(true);
  }

  /**
   * Creates a new test frame with standard scale fact, given window size and
   * given center
   * 
   * @param d
   *          the size of the window
   * @param center
   *          the center of the window
   */
  public GraphicalTestFrame(
      Dimension d,
      Vektor center) {

    super();
    this.addWindowListener(new WindowClosingAdapter(true));
    scalefact = SCALE_STANDARD;
    dimension.width = d.width;
    dimension.height = d.height;
    setPreferredSize(dimension);
    this.center.copy(center);
    setContentPane(new ContentPanel());
    pack();
    setVisible(true);
  }

  /**
   * Creates a new test frame with standard scale fact, standard window size and
   * center (0,0)
   * 
   * @param scale
   *          1 is normal scaling, higher values zoom closer, lower values zoom
   *          away
   */
  public GraphicalTestFrame(
      double scale) {

    super();
    this.addWindowListener(new WindowClosingAdapter(true));
    scalefact = SCALE_STANDARD * scale;
    setContentPane(new ContentPanel());
    setPreferredSize(dimension);
    pack();
    setVisible(true);
  }

  /**
   * Creates a new test frame with standard scale fact, given window size and
   * center (0,0)
   * 
   * @param d
   *          the size of the window
   * @param scale
   *          1 is normal scaling, higher values zoom closer, lower values zoom
   *          away
   */
  public GraphicalTestFrame(
      Dimension d,
      double scale) {

    super();
    this.addWindowListener(new WindowClosingAdapter(true));
    scalefact = SCALE_STANDARD * scale;
    dimension.width = d.width;
    dimension.height = d.height;
    setPreferredSize(dimension);
    setContentPane(new ContentPanel());
    pack();
    setVisible(true);
  }

  /**
   * Creates a new test frame with standard scale fact, standard window size and
   * given center
   * 
   * @param center
   *          the center of the window
   * @param scale
   *          1 is normal scaling, higher values zoom closer, lower values zoom
   *          away
   */
  public GraphicalTestFrame(
      Vektor center,
      double scale) {

    super();
    this.addWindowListener(new WindowClosingAdapter(true));
    scalefact = SCALE_STANDARD * scale;
    this.center.copy(center);
    setContentPane(new ContentPanel());
    setPreferredSize(dimension);
    pack();
    setVisible(true);
  }

  /**
   * Creates a new test frame with standard scale fact, given window size and
   * given center
   * 
   * @param d
   *          the size of the window
   * @param center
   *          the center of the window
   * @param scale
   *          1 is normal scaling, higher values zoom closer, lower values zoom
   *          away
   */
  public GraphicalTestFrame(
      Dimension d,
      Vektor center,
      double scale) {

    super();
    this.addWindowListener(new WindowClosingAdapter(true));
    scalefact = SCALE_STANDARD * scale;
    dimension.width = d.width;
    dimension.height = d.height;
    setPreferredSize(dimension);
    this.center.copy(center);
    setContentPane(new ContentPanel());
    pack();
    setVisible(true);
  }

  class ContentPanel
      extends JPanel {

    ButtonPanel bp = new ButtonPanel(this);
    MainPanel   mp = new MainPanel();

    /**
     * used as content pane
     */
    public ContentPanel() {

      GridBagLayout gbl = new GridBagLayout();
      GridBagConstraints gbc = new GridBagConstraints();
      setLayout(gbl);
      setPreferredSize(dimension);
      setMinimumSize(dimension);

      gbc.anchor = GridBagConstraints.CENTER;
      gbc.fill = GridBagConstraints.BOTH;
      gbc.gridx = 0;
      gbc.gridy = 0;
      gbc.gridwidth = 1;
      gbc.gridheight = 1;
      gbc.weightx = 1;
      gbc.weighty = 1;
      gbl.setConstraints(mp, gbc);
      add(mp);

      gbc.gridy = 1;
      gbc.weighty = 0;
      gbl.setConstraints(bp, gbc);
      add(bp);
    }
  }

  class ButtonPanel
      extends JPanel
      implements ActionListener {

    JButton      nextSituation = new JButton("next Situation");
    JButton      nextCycle     = new JButton("next Cycle");
    ContentPanel parent;

    /**
     * This panel holds two buttons
     * 
     * @param panel
     */
    public ButtonPanel(
        ContentPanel panel) {

      parent = panel;

      GridBagLayout gbl = new GridBagLayout();
      GridBagConstraints gbc = new GridBagConstraints();
      setLayout(gbl);
      setPreferredSize(new Dimension(dimension.width, 40));
      setMinimumSize(new Dimension(dimension.width, 40));
      nextSituation.addActionListener(this);
      nextCycle.addActionListener(this);

      gbc.anchor = GridBagConstraints.CENTER;
      gbc.fill = GridBagConstraints.NONE;
      gbc.gridx = 0;
      gbc.gridy = 0;
      gbc.gridwidth = 1;
      gbc.gridheight = 1;
      gbc.weightx = 1;
      gbc.weighty = 1;
      gbl.setConstraints(nextCycle, gbc);
      add(nextCycle);

      gbc.gridx = 1;
      gbl.setConstraints(nextSituation, gbc);
      add(nextSituation);
    }

    /**
     * (non-Javadoc)
     * 
     * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
     */
    public void actionPerformed(ActionEvent e) {

      if (e.getSource() == nextCycle) {
        nextCycle();
      }
      if (e.getSource() == nextSituation) {
        nextSituation();
      }
      parent.repaint();

    }

  }

  class MainPanel
      extends JPanel {

    /**
     * On this panel everything is drawn
     */
    public MainPanel() {

      setPreferredSize(new Dimension(dimension.width, dimension.height - 40));
    }

    /**
     * (non-Javadoc)
     * 
     * @see javax.swing.JComponent#paint(java.awt.Graphics)
     */
    public void paint(Graphics g) {

      if (fresh) {
        fresh = false;
        nextSituation();
      }

      g.setColor(Color.WHITE);
      g.fillRect(0, 0, dimension.width, dimension.height);
      g.setColor(Color.BLACK);
      double availableX = dimension.height - X_OFFSET - 40;
      double availableY = dimension.width - Y_OFFSET - 45;
      availableX /= scalefact;
      availableY /= scalefact;
      int avX = (int) availableX;
      int avY = (int) availableY;
      minX = Math.round((float) center.x) - (avX / 2 + avX % 2);
      maxX = Math.round((float) center.x) + (avX / 2);
      minY = Math.round((float) center.y) - (avY / 2 + avY % 2);
      maxY = Math.round((float) center.y) + (avY / 2);
      drawLine(g, (int) minX, (int) minY, (int) minX, (int) maxY);
      drawLine(g, (int) minX, (int) minY, (int) maxX, (int) minY);
      for (int i = Math.round((float) minX) + 1; i <= Math.round((float) maxX); i++) {
        g.setColor(Color.LIGHT_GRAY);
        drawLine(g, i, (int) minY, i, (int) maxY);
        g.setColor(Color.BLACK);
        drawString(g, i + ".0", i, minY, -40, 5);
      }
      for (int j = Math.round((float) minY) + 1; j <= Math.round((float) maxY); j++) {
        g.setColor(Color.LIGHT_GRAY);
        drawLine(g, (int) minX, j, (int) maxX, j);
        g.setColor(Color.BLACK);
        drawString(g, j + ".0", maxX, j, -18, -5);
      }
      paintSituation(g);
    }

  }

  /**
   * Sets the center
   * 
   * @param v
   *          the new center
   */
  public void setCenter(Vektor v) {

    center.copy(v);
  }

  /**
   * Sets the scale fact
   * 
   * @param scale
   *          the new scale fact
   */
  public void setScaleFact(double scale) {

    scalefact = SCALE_STANDARD * scale;
  }

  abstract protected void nextSituation();

  abstract protected void nextCycle();

  abstract protected void paintSituation(Graphics g);

  protected void drawLine(Graphics g,
      double x1,
      double y1,
      double x2,
      double y2) {

    shapeLine.x1 = (y1 - minY) * scalefact + X_OFFSET;
    shapeLine.y1 = (maxX - x1) * scalefact + Y_OFFSET;
    shapeLine.x2 = (y2 - minY) * scalefact + X_OFFSET;
    shapeLine.y2 = (maxX - x2) * scalefact + Y_OFFSET;
    ((Graphics2D) g).draw(shapeLine);
  }

  protected void drawString(Graphics g,
      String s,
      double x,
      double y) {

    int xPos = (int) ((y - minY) * scalefact) + X_OFFSET;
    int yPos = (int) ((maxX - x) * scalefact) + Y_OFFSET;
    g.drawString(s, xPos, yPos);
  }

  protected void drawString(Graphics g,
      String s,
      double x,
      double y,
      int absXoff,
      int absYoff) {

    int xPos = (int) ((y - minY) * scalefact) + X_OFFSET + absXoff;
    int yPos = (int) ((maxX - x) * scalefact) + Y_OFFSET + absYoff;
    g.drawString(s, xPos, yPos);
  }

  protected void draw(Graphics g,
      Vektor v) {

    int xPos = (int) ((v.y - minY) * scalefact) + X_OFFSET;
    int yPos = (int) ((maxX - v.x) * scalefact) + Y_OFFSET;
    g.drawLine(xPos - 5, yPos - 5, xPos + 5, yPos + 5);
    g.drawLine(xPos - 5, yPos + 5, xPos + 5, yPos - 5);
  }

  protected void draw(Graphics g,
      LineSegment line) {

    shapeLine.x1 = (line.getPoint1().y - minY) * scalefact + X_OFFSET;
    shapeLine.y1 = (maxX - line.getPoint1().x) * scalefact + Y_OFFSET;
    shapeLine.x2 = (line.getPoint2().y - minY) * scalefact + X_OFFSET;
    shapeLine.y2 = (maxX - line.getPoint2().x) * scalefact + Y_OFFSET;
    ((Graphics2D) g).draw(shapeLine);
  }

  protected void draw(Graphics g,
      Circle circ) {

    double centX = (circ.getCenter().y - minY) * scalefact + X_OFFSET;
    double centY = (maxX - circ.getCenter().x) * scalefact + Y_OFFSET;
    double radius = circ.getRadius() * scalefact;
    shapeArc.x = centX - radius;
    shapeArc.y = centY - radius;
    shapeArc.width = 2 * radius;
    shapeArc.height = 2 * radius;
    shapeArc.start = 0;
    shapeArc.extent = 360;
    shapeArc.setArcType(Arc2D.OPEN);
    ((Graphics2D) g).draw(shapeArc);
  }

  protected void fill(Graphics g,
      Circle circ) {

    double centX = (circ.getCenter().y - minY) * scalefact + X_OFFSET;
    double centY = (maxX - circ.getCenter().x) * scalefact + Y_OFFSET;
    double radius = circ.getRadius() * scalefact;
    shapeArc.x = centX - radius;
    shapeArc.y = centY - radius;
    shapeArc.width = 2 * radius;
    shapeArc.height = 2 * radius;
    shapeArc.start = 0;
    shapeArc.extent = 360;
    shapeArc.setArcType(Arc2D.PIE);
    ((Graphics2D) g).fill(shapeArc);
  }

  protected void draw(Graphics g,
      CircleSegment circ) {

    double centX = (circ.getCenter().y - minY) * scalefact + X_OFFSET;
    double centY = (maxX - circ.getCenter().x) * scalefact + Y_OFFSET;
    double radius = circ.getRadius() * scalefact;
    shapeArc.x = centX - radius;
    shapeArc.y = centY - radius;
    shapeArc.width = 2 * radius;
    shapeArc.height = 2 * radius;
    shapeArc.start = circ.getStartAngle();
    shapeArc.extent = circ.getAngleDiff();
    shapeArc.setArcType(Arc2D.OPEN);
    ((Graphics2D) g).draw(shapeArc);
  }

  protected void fill(Graphics g,
      CircleSegment circ) {

    double centX = (circ.getCenter().y - minY) * scalefact + X_OFFSET;
    double centY = (maxX - circ.getCenter().x) * scalefact + Y_OFFSET;
    double radius = circ.getRadius() * scalefact;
    shapeArc.x = centX - radius;
    shapeArc.y = centY - radius;
    shapeArc.width = 2 * radius;
    shapeArc.height = 2 * radius;
    shapeArc.start = circ.getStartAngle();
    shapeArc.extent = circ.getAngleDiff();
    shapeArc.setArcType(Arc2D.PIE);
    ((Graphics2D) g).fill(shapeArc);
  }

  protected void draw(Graphics g,
      StraightLine line) {

    Vektor p1 = new Vektor();
    line.getPointWithXValue(minX, p1);
    Vektor p2 = new Vektor();
    line.getPointWithXValue(maxX, p2);
    if (p1.isEmpty() || p1.y < minY || p1.y > maxY) {
      line.getPointWithYValue(minY, p1);
    }
    if (p1.isEmpty() || p1.x < minX || p1.x > maxX) {
      line.getPointWithYValue(maxY, p1);
    }
    if (p2.isEmpty() || p2.y < minY || p2.y > maxY) {
      line.getPointWithYValue(maxY, p2);
    }
    if (p2.isEmpty() || p2.x < minX || p2.x > maxX) {
      line.getPointWithYValue(minY, p2);
    }
    shapeLine.x1 = (p1.y - minY) * scalefact + X_OFFSET;
    shapeLine.y1 = (maxX - p1.x) * scalefact + Y_OFFSET;
    shapeLine.x2 = (p2.y - minY) * scalefact + X_OFFSET;
    shapeLine.y2 = (maxX - p2.x) * scalefact + Y_OFFSET;
    ((Graphics2D) g).draw(shapeLine);
  }

  protected void drawArrow(Graphics g,
      double x1,
      double y1,
      double x2,
      double y2) {

    drawLine(g, x1, y1, x2, y2);
    Vektor v = new Vektor(Vektor.XY, x2, y2);
    double vAng = v.getAngleTo(new Vektor(Vektor.XY, x1, y1));
    double vLen = v.getDistance(new Vektor(Vektor.XY, x1, y1));
    Vektor v1 = v.add(new Vektor(vLen / 4, vAng + 30));
    drawLine(g, x2, y2, v1.x, v1.y);
    v1 = v.add(new Vektor(vLen / 4, vAng - 30));
    drawLine(g, x2, y2, v1.x, v1.y);
  }

  protected void drawRect(Graphics g,
      double x1,
      double y1,
      double x2,
      double y2) {

    shapeRect.x = (y1 - minY) * scalefact + X_OFFSET;
    shapeRect.y = (maxX - x1) * scalefact + Y_OFFSET;
    shapeRect.width = (y2 - minY) * scalefact + X_OFFSET - shapeRect.x;
    shapeRect.height = (x2 - minX) * scalefact + Y_OFFSET - shapeRect.y;
    ((Graphics2D) g).draw(shapeRect);
  }

  protected void fillRect(Graphics g,
      double x1,
      double y1,
      double x2,
      double y2) {

    shapeRect.x = (y1 - minY) * scalefact + X_OFFSET;
    shapeRect.y = (maxX - x1) * scalefact + Y_OFFSET;
    shapeRect.width = (y2 - minY) * scalefact + X_OFFSET - shapeRect.x;
    shapeRect.height = (maxX - x2) * scalefact + Y_OFFSET - shapeRect.y;
    ((Graphics2D) g).fill(shapeRect);
  }

  protected void draw(Graphics g,
      Ball b) {

    actColor = g.getColor();
    g.setColor(Color.WHITE);
    dummyCircle.setCenter(b.getPosition());
    dummyCircle.setRadius(SConf.getInstance().BALL_SIZE);
    fill(g, dummyCircle);
    g.setColor(actColor);
    draw(g, dummyCircle);
  }

  protected void draw(Graphics g,
      Player p) {

    actColor = g.getColor();
    dummyCircleSegment.copyCenter(p.getPosition());
    dummyCircleSegment.setRadius(p.getPConf().PLAYER_SIZE);
    dummyCircleSegment.setStartAngle(p.getBodyDir() - 90);
    dummyCircleSegment.setEndAngle(p.getBodyDir() + 90);
    fill(g, dummyCircleSegment);
    g.setColor(Color.black);
    dummyCircleSegment.setStartAngle(p.getBodyDir() + 90);
    dummyCircleSegment.setEndAngle(p.getBodyDir() - 90);
    fill(g, dummyCircleSegment);
    dummyCircle.copy(dummyCircleSegment.getCircle());
    draw(g, dummyCircle);
    g.setColor(actColor);
  }

  protected void draw(Graphics g,
      ReachableArea ra,
      boolean backAllowed) {

    if (!backAllowed) {
      drawReachableForward(g, ra);
      return;
    }
    drawReachableBackward(g, ra);
  }

  private void drawReachableForward(Graphics g,
      ReachableArea ra) {

    if (ra.getDash0() == 0) {
      dummyCircle.setCenter(ra.getPos());
      dummyCircle.setRadius(ra.getReachDist());
      draw(g, dummyCircle);
      return;
    }
    if (ra.getDash0() > 0) {
      dummyCircleSegment.setRadius(ra.getReachDist());
      dummyCircleSegment.copyCenter(ra.getCornerPointsForward()[0]);
      dummyCircleSegment.setStartAngle(Vektor.normalize(ra.getBodyDir() - 90));
      dummyCircleSegment.setEndAngle(Vektor.normalize(ra.getBodyDir() + 90));
      draw(g, dummyCircleSegment);
      if (ra.getCycles() == 1) {
        dummyCircleSegment.setRadius(ra.getReachDist());
        dummyCircleSegment.copyCenter(ra.getPos());
        dummyCircleSegment
            .setStartAngle(Vektor.normalize(ra.getBodyDir() + 90));
        dummyCircleSegment.setEndAngle(Vektor.normalize(ra.getBodyDir() - 90));
        draw(g, dummyCircleSegment);
        dummyVektor.setVektor(ra.getReachDist(), Vektor.normalize(ra
            .getBodyDir() + 90));
        dummyVektor.addToThis(ra.getCornerPointsForward()[0]);
        dummyLineSegment.copyPoint1(dummyVektor);
        dummyVektor.setVektor(ra.getReachDist(), Vektor.normalize(ra
            .getBodyDir() + 90));
        dummyVektor.addToThis(ra.getPos());
        dummyLineSegment.copyPoint2(dummyVektor);
        draw(g, dummyLineSegment);
        dummyVektor.setVektor(ra.getReachDist(), Vektor.normalize(ra
            .getBodyDir() - 90));
        dummyVektor.addToThis(ra.getCornerPointsForward()[0]);
        dummyLineSegment.copyPoint1(dummyVektor);
        dummyVektor.setVektor(ra.getReachDist(), Vektor.normalize(ra
            .getBodyDir() - 90));
        dummyVektor.addToThis(ra.getPos());
        dummyLineSegment.copyPoint2(dummyVektor);
        draw(g, dummyLineSegment);
      }
      else {
        dummyVektor.setVektor(ra.getReachDist(), Vektor.normalize(ra
            .getBodyDir() + 90));
        dummyVektor.addToThis(ra.getCornerPointsForward()[0]);
        dummyLineSegment.copyPoint1(dummyVektor);
        dummyVektor2.setVektor(Math.max(0, ra.getDash0() - ra.getDash1()),
            Vektor.normalize(ra.getBodyDir() + 180));
        dummyVektor.addToThis(dummyVektor2);
        dummyLineSegment.copyPoint2(dummyVektor);
        draw(g, dummyLineSegment);
        dummyVektor.setVektor(ra.getReachDist(), Vektor.normalize(ra
            .getBodyDir() - 90));
        dummyVektor.addToThis(ra.getCornerPointsForward()[0]);
        dummyLineSegment.copyPoint1(dummyVektor);
        dummyVektor2.setVektor(Math.max(0, ra.getDash0() - ra.getDash1()),
            Vektor.normalize(ra.getBodyDir() + 180));
        dummyVektor.addToThis(dummyVektor2);
        dummyLineSegment.copyPoint2(dummyVektor);
        draw(g, dummyLineSegment);
      }
    }
    if (ra.getDash1() > 0) {
      if (ra.getTurn1() < 180) {
        dummyCircleSegment.copyCenter(ra.getPos());
        dummyCircleSegment.setRadius(ra.getDash1() + ra.getReachDist());
        dummyCircleSegment.setStartAngle(Vektor.normalize(ra.getBodyDir()
            - ra.getTurn1()));
        dummyCircleSegment.setEndAngle(Vektor.normalize(ra.getBodyDir()));
        draw(g, dummyCircleSegment);
        dummyCircleSegment.setStartAngle(Vektor.normalize(ra.getBodyDir()));
        dummyCircleSegment.setEndAngle(Vektor.normalize(ra.getBodyDir()
            + ra.getTurn1()));
        draw(g, dummyCircleSegment);
        dummyCircleSegment.setRadius(ra.getReachDist());
        dummyCircleSegment.copyCenter(ra.getCornerPointsForward()[1]);
        dummyCircleSegment.setStartAngle(Vektor.normalize(ra.getBodyDir()
            + ra.getTurn1()));
        dummyCircleSegment.setEndAngle(Vektor.normalize(ra.getBodyDir()
            + ra.getTurn1()
            + 90));
        draw(g, dummyCircleSegment);
        dummyCircleSegment.copyCenter(ra.getCornerPointsForward()[2]);
        dummyCircleSegment.setStartAngle(Vektor.normalize(ra.getBodyDir()
            - ra.getTurn1()
            - 90));
        dummyCircleSegment.setEndAngle(Vektor.normalize(ra.getBodyDir()
            - ra.getTurn1()));
        draw(g, dummyCircleSegment);
        dummyVektor.setVektor(ra.getReachDist(), Vektor.normalize(ra
            .getBodyDir()
            + ra.getTurn1()
            + 90));
        dummyVektor.addToThis(ra.getCornerPointsForward()[1]);
        dummyLineSegment.copyPoint1(dummyVektor);
        dummyVektor2.setVektor(ra.getDash1() - ra.getDash2(), Vektor
            .normalize(ra.getBodyDir() + ra.getTurn1() + 180));
        dummyVektor.addToThis(dummyVektor2);
        dummyLineSegment.copyPoint2(dummyVektor);
        draw(g, dummyLineSegment);
        dummyVektor.setVektor(ra.getReachDist(), Vektor.normalize(ra
            .getBodyDir()
            - ra.getTurn1()
            - 90));
        dummyVektor.addToThis(ra.getCornerPointsForward()[2]);
        dummyLineSegment.copyPoint1(dummyVektor);
        dummyVektor2.setVektor(ra.getDash1() - ra.getDash2(), Vektor
            .normalize(ra.getBodyDir() - ra.getTurn1() + 180));
        dummyVektor.addToThis(dummyVektor2);
        dummyLineSegment.copyPoint2(dummyVektor);
        draw(g, dummyLineSegment);
        if (ra.getCycles() == 2) {
          if (ra.getTurn1() < 90) {
            dummyCircleSegment.copyCenter(ra.getPos());
            dummyCircleSegment.setRadius(ra.getReachDist());
            dummyCircleSegment.setStartAngle(Vektor.normalize(ra.getBodyDir()
                + ra.getTurn1()
                + 90));
            dummyCircleSegment.setEndAngle(Vektor.normalize(ra.getBodyDir()
                - ra.getTurn1()
                - 90));
            draw(g, dummyCircleSegment);
          }
        }
      }
      else {
        dummyCircle.setCenter(ra.getPos());
        dummyCircle.setRadius(ra.getDash1() + ra.getReachDist());
        draw(g, dummyCircle);
        return;
      }
    }
    if (ra.getDash2() > 0) {
      if (ra.getTurn2() < 180) {
        dummyCircleSegment.copyCenter(ra.getPos());
        dummyCircleSegment.setRadius(ra.getDash2() + ra.getReachDist());
        dummyCircleSegment.setStartAngle(Vektor.normalize(ra.getBodyDir()
            - ra.getTurn2()));
        dummyCircleSegment.setEndAngle(Vektor.normalize(ra.getBodyDir()
            - ra.getTurn1()));
        draw(g, dummyCircleSegment);
        dummyCircleSegment.setStartAngle(Vektor.normalize(ra.getBodyDir()
            + ra.getTurn1()));
        dummyCircleSegment.setEndAngle(Vektor.normalize(ra.getBodyDir()
            + ra.getTurn2()));
        draw(g, dummyCircleSegment);
        dummyCircleSegment.setRadius(ra.getReachDist());
        dummyCircleSegment.copyCenter(ra.getCornerPointsForward()[3]);
        dummyCircleSegment.setStartAngle(Vektor.normalize(ra.getBodyDir()
            + ra.getTurn2()));
        dummyCircleSegment.setEndAngle(Vektor.normalize(ra.getBodyDir()
            + ra.getTurn2()
            + 90));
        draw(g, dummyCircleSegment);
        dummyCircleSegment.copyCenter(ra.getCornerPointsForward()[4]);
        dummyCircleSegment.setStartAngle(Vektor.normalize(ra.getBodyDir()
            - ra.getTurn2()
            - 90));
        dummyCircleSegment.setEndAngle(Vektor.normalize(ra.getBodyDir()
            - ra.getTurn2()));
        draw(g, dummyCircleSegment);
        dummyVektor.setVektor(ra.getReachDist(), Vektor.normalize(ra
            .getBodyDir()
            + ra.getTurn2()
            + 90));
        dummyVektor.addToThis(ra.getCornerPointsForward()[3]);
        dummyLineSegment.copyPoint1(dummyVektor);
        dummyVektor2.setVektor(ra.getDash2() - ra.getDash3(), Vektor
            .normalize(ra.getBodyDir() + ra.getTurn2() + 180));
        dummyVektor.addToThis(dummyVektor2);
        dummyLineSegment.copyPoint2(dummyVektor);
        draw(g, dummyLineSegment);
        dummyVektor.setVektor(ra.getReachDist(), Vektor.normalize(ra
            .getBodyDir()
            - ra.getTurn2()
            - 90));
        dummyVektor.addToThis(ra.getCornerPointsForward()[4]);
        dummyLineSegment.copyPoint1(dummyVektor);
        dummyVektor2.setVektor(ra.getDash2() - ra.getDash3(), Vektor
            .normalize(ra.getBodyDir() - ra.getTurn2() + 180));
        dummyVektor.addToThis(dummyVektor2);
        dummyLineSegment.copyPoint2(dummyVektor);
        draw(g, dummyLineSegment);
        if (ra.getCycles() == 3) {
          if (ra.getTurn2() < 90) {
            dummyCircleSegment.copyCenter(ra.getPos());
            dummyCircleSegment.setRadius(ra.getReachDist());
            dummyCircleSegment.setStartAngle(Vektor.normalize(ra.getBodyDir()
                + ra.getTurn2()
                + 90));
            dummyCircleSegment.setEndAngle(Vektor.normalize(ra.getBodyDir()
                - ra.getTurn2()
                - 90));
            draw(g, dummyCircleSegment);
          }
        }
      }
      else {
        dummyCircleSegment.copyCenter(ra.getPos());
        dummyCircleSegment.setStartAngle(Vektor.normalize(ra.getBodyDir()
            + ra.getTurn1()));
        dummyCircleSegment.setEndAngle(Vektor.normalize(ra.getBodyDir()
            - ra.getTurn1()));
        dummyCircleSegment.setRadius(ra.getDash2() + ra.getReachDist());
        draw(g, dummyCircleSegment);
        return;
      }
    }
    if (ra.getDash3() > 0) {
      if (ra.getTurn3() < 180) {
        dummyCircleSegment.copyCenter(ra.getPos());
        dummyCircleSegment.setRadius(ra.getDash3() + ra.getReachDist());
        dummyCircleSegment.setStartAngle(Vektor.normalize(ra.getBodyDir()
            - ra.getTurn3()));
        dummyCircleSegment.setEndAngle(Vektor.normalize(ra.getBodyDir()
            - ra.getTurn2()));
        draw(g, dummyCircleSegment);
        dummyCircleSegment.setStartAngle(Vektor.normalize(ra.getBodyDir()
            + ra.getTurn2()));
        dummyCircleSegment.setEndAngle(Vektor.normalize(ra.getBodyDir()
            + ra.getTurn3()));
        draw(g, dummyCircleSegment);
        dummyCircleSegment.setRadius(ra.getReachDist());
        dummyCircleSegment.copyCenter(ra.getCornerPointsForward()[5]);
        dummyCircleSegment.setStartAngle(Vektor.normalize(ra.getBodyDir()
            + ra.getTurn3()));
        dummyCircleSegment.setEndAngle(Vektor.normalize(ra.getBodyDir()
            + ra.getTurn3()
            + 90));
        draw(g, dummyCircleSegment);
        dummyCircleSegment.copyCenter(ra.getCornerPointsForward()[6]);
        dummyCircleSegment.setStartAngle(Vektor.normalize(ra.getBodyDir()
            - ra.getTurn3()
            - 90));
        dummyCircleSegment.setEndAngle(Vektor.normalize(ra.getBodyDir()
            - ra.getTurn3()));
        draw(g, dummyCircleSegment);
        dummyVektor.setVektor(ra.getReachDist(), Vektor.normalize(ra
            .getBodyDir()
            + ra.getTurn3()
            + 90));
        dummyVektor.addToThis(ra.getCornerPointsForward()[5]);
        dummyLineSegment.copyPoint1(dummyVektor);
        dummyVektor2.setVektor(ra.getDash3() - ra.getDash4(), Vektor
            .normalize(ra.getBodyDir() + ra.getTurn3() + 180));
        dummyVektor.addToThis(dummyVektor2);
        dummyLineSegment.copyPoint2(dummyVektor);
        draw(g, dummyLineSegment);
        dummyVektor.setVektor(ra.getReachDist(), Vektor.normalize(ra
            .getBodyDir()
            - ra.getTurn3()
            - 90));
        dummyVektor.addToThis(ra.getCornerPointsForward()[6]);
        dummyLineSegment.copyPoint1(dummyVektor);
        dummyVektor2.setVektor(ra.getDash3() - ra.getDash4(), Vektor
            .normalize(ra.getBodyDir() - ra.getTurn3() + 180));
        dummyVektor.addToThis(dummyVektor2);
        dummyLineSegment.copyPoint2(dummyVektor);
        draw(g, dummyLineSegment);
      }
      else {
        dummyCircleSegment.copyCenter(ra.getPos());
        dummyCircleSegment.setStartAngle(Vektor.normalize(ra.getBodyDir()
            + ra.getTurn2()));
        dummyCircleSegment.setEndAngle(Vektor.normalize(ra.getBodyDir()
            - ra.getTurn2()));
        dummyCircleSegment.setRadius(ra.getDash3() + ra.getReachDist());
        draw(g, dummyCircleSegment);
        return;
      }
    }
    if (ra.getDash4() > 0) {
      dummyCircleSegment.copyCenter(ra.getPos());
      dummyCircleSegment.setStartAngle(Vektor.normalize(ra.getBodyDir()
          + ra.getTurn3()));
      dummyCircleSegment.setEndAngle(Vektor.normalize(ra.getBodyDir()
          - ra.getTurn3()));
      dummyCircleSegment.setRadius(ra.getDash4() + ra.getReachDist());
      draw(g, dummyCircleSegment);
      return;
    }

  }

  private void drawReachableBackward(Graphics g,
      ReachableArea ra) {

    if (ra.getDash0() == 0) {
      dummyCircle.setCenter(ra.getPos());
      dummyCircle.setRadius(ra.getReachDist());
      draw(g, dummyCircle);
      return;
    }
    if (ra.getDash0() > 0) {
      dummyCircleSegment.setRadius(ra.getReachDist());
      dummyCircleSegment.copyCenter(ra.getCornerPointsBackward()[0]);
      dummyCircleSegment.setStartAngle(Vektor.normalize(ra.getBodyDir() - 90));
      dummyCircleSegment.setEndAngle(Vektor.normalize(ra.getBodyDir() + 90));
      draw(g, dummyCircleSegment);
      dummyCircleSegment.setRadius(ra.getReachDist());
      dummyCircleSegment.copyCenter(ra.getCornerPointsBackward()[5]);
      dummyCircleSegment.setStartAngle(Vektor.normalize(ra.getBodyDir() + 90));
      dummyCircleSegment.setEndAngle(Vektor.normalize(ra.getBodyDir() - 90));
      draw(g, dummyCircleSegment);
      if (ra.getCycles() == 1) {
        dummyVektor.setVektor(ra.getReachDist(), Vektor.normalize(ra
            .getBodyDir() + 90));
        dummyVektor.addToThis(ra.getCornerPointsBackward()[0]);
        dummyLineSegment.copyPoint1(dummyVektor);
        dummyVektor.setVektor(ra.getReachDist(), Vektor.normalize(ra
            .getBodyDir() + 90));
        dummyVektor.addToThis(ra.getCornerPointsBackward()[5]);
        dummyLineSegment.copyPoint2(dummyVektor);
        draw(g, dummyLineSegment);
        dummyVektor.setVektor(ra.getReachDist(), Vektor.normalize(ra
            .getBodyDir() - 90));
        dummyVektor.addToThis(ra.getCornerPointsBackward()[0]);
        dummyLineSegment.copyPoint1(dummyVektor);
        dummyVektor.setVektor(ra.getReachDist(), Vektor.normalize(ra
            .getBodyDir() - 90));
        dummyVektor.addToThis(ra.getCornerPointsBackward()[5]);
        dummyLineSegment.copyPoint2(dummyVektor);
        draw(g, dummyLineSegment);
      }
      else {
        dummyVektor.setVektor(ra.getReachDist(), Vektor.normalize(ra
            .getBodyDir() + 90));
        dummyVektor.addToThis(ra.getCornerPointsBackward()[0]);
        dummyLineSegment.copyPoint1(dummyVektor);
        dummyVektor2.setVektor(Math.max(0, ra.getDash0() - ra.getDash1()),
            Vektor.normalize(ra.getBodyDir() + 180));
        dummyVektor.addToThis(dummyVektor2);
        dummyLineSegment.copyPoint2(dummyVektor);
        draw(g, dummyLineSegment);
        dummyVektor.setVektor(ra.getReachDist(), Vektor.normalize(ra
            .getBodyDir() - 90));
        dummyVektor.addToThis(ra.getCornerPointsBackward()[0]);
        dummyLineSegment.copyPoint1(dummyVektor);
        dummyVektor2.setVektor(Math.max(0, ra.getDash0() - ra.getDash1()),
            Vektor.normalize(ra.getBodyDir() + 180));
        dummyVektor.addToThis(dummyVektor2);
        dummyLineSegment.copyPoint2(dummyVektor);
        draw(g, dummyLineSegment);
        dummyVektor.setVektor(ra.getReachDist(), Vektor.normalize(ra
            .getBodyDir() - 90));
        dummyVektor.addToThis(ra.getCornerPointsBackward()[5]);
        dummyLineSegment.copyPoint1(dummyVektor);
        dummyVektor2.setVektor(Math.max(0, ra.getDash0() - ra.getDash1()),
            Vektor.normalize(ra.getBodyDir()));
        dummyVektor.addToThis(dummyVektor2);
        dummyLineSegment.copyPoint2(dummyVektor);
        draw(g, dummyLineSegment);
        dummyVektor.setVektor(ra.getReachDist(), Vektor.normalize(ra
            .getBodyDir() + 90));
        dummyVektor.addToThis(ra.getCornerPointsBackward()[5]);
        dummyLineSegment.copyPoint1(dummyVektor);
        dummyVektor2.setVektor(Math.max(0, ra.getDash0() - ra.getDash1()),
            Vektor.normalize(ra.getBodyDir()));
        dummyVektor.addToThis(dummyVektor2);
        dummyLineSegment.copyPoint2(dummyVektor);
        draw(g, dummyLineSegment);
      }
    }
    if (ra.getDash1() > 0) {
      if (ra.getTurn1() < 90) {
        dummyCircleSegment.copyCenter(ra.getPos());
        dummyCircleSegment.setRadius(ra.getDash1() + ra.getReachDist());
        dummyCircleSegment.setStartAngle(Vektor.normalize(ra.getBodyDir()
            - ra.getTurn1()));
        dummyCircleSegment.setEndAngle(Vektor.normalize(ra.getBodyDir()));
        draw(g, dummyCircleSegment);
        dummyCircleSegment.setStartAngle(Vektor.normalize(ra.getBodyDir()));
        dummyCircleSegment.setEndAngle(Vektor.normalize(ra.getBodyDir()
            + ra.getTurn1()));
        draw(g, dummyCircleSegment);
        dummyCircleSegment.setRadius(ra.getDash1() + ra.getReachDist());
        dummyCircleSegment.setStartAngle(Vektor.normalize(ra.getBodyDir()
            - ra.getTurn1()
            + 180));
        dummyCircleSegment.setEndAngle(Vektor.normalize(ra.getBodyDir() + 180));
        draw(g, dummyCircleSegment);
        dummyCircleSegment.setStartAngle(Vektor
            .normalize(ra.getBodyDir() + 180));
        dummyCircleSegment.setEndAngle(Vektor.normalize(ra.getBodyDir()
            + ra.getTurn1()
            + 180));
        draw(g, dummyCircleSegment);

        dummyCircleSegment.setRadius(ra.getReachDist());
        dummyCircleSegment.copyCenter(ra.getCornerPointsBackward()[1]);
        dummyCircleSegment.setStartAngle(Vektor.normalize(ra.getBodyDir()
            + ra.getTurn1()));
        dummyCircleSegment.setEndAngle(Vektor.normalize(ra.getBodyDir()
            + ra.getTurn1()
            + 90));
        draw(g, dummyCircleSegment);
        dummyCircleSegment.copyCenter(ra.getCornerPointsBackward()[2]);
        dummyCircleSegment.setStartAngle(Vektor.normalize(ra.getBodyDir()
            - ra.getTurn1()
            - 90));
        dummyCircleSegment.setEndAngle(Vektor.normalize(ra.getBodyDir()
            - ra.getTurn1()));
        draw(g, dummyCircleSegment);
        dummyCircleSegment.copyCenter(ra.getCornerPointsBackward()[6]);
        dummyCircleSegment.setStartAngle(Vektor.normalize(ra.getBodyDir()
            + ra.getTurn1()
            + 180));
        dummyCircleSegment.setEndAngle(Vektor.normalize(ra.getBodyDir()
            + ra.getTurn1()
            - 90));
        draw(g, dummyCircleSegment);
        dummyCircleSegment.copyCenter(ra.getCornerPointsBackward()[7]);
        dummyCircleSegment.setStartAngle(Vektor.normalize(ra.getBodyDir()
            - ra.getTurn1()
            + 90));
        dummyCircleSegment.setEndAngle(Vektor.normalize(ra.getBodyDir()
            - ra.getTurn1()
            + 180));
        draw(g, dummyCircleSegment);

        dummyVektor.setVektor(ra.getReachDist(), Vektor.normalize(ra
            .getBodyDir()
            + ra.getTurn1()
            + 90));
        dummyVektor.addToThis(ra.getCornerPointsBackward()[1]);
        dummyLineSegment.copyPoint1(dummyVektor);
        dummyVektor2.setVektor(ra.getDash1() - ra.getDash2(), Vektor
            .normalize(ra.getBodyDir() + ra.getTurn1() + 180));
        dummyVektor.addToThis(dummyVektor2);
        dummyLineSegment.copyPoint2(dummyVektor);
        draw(g, dummyLineSegment);
        dummyVektor.setVektor(ra.getReachDist(), Vektor.normalize(ra
            .getBodyDir()
            - ra.getTurn1()
            - 90));
        dummyVektor.addToThis(ra.getCornerPointsBackward()[2]);
        dummyLineSegment.copyPoint1(dummyVektor);
        dummyVektor2.setVektor(ra.getDash1() - ra.getDash2(), Vektor
            .normalize(ra.getBodyDir() - ra.getTurn1() + 180));
        dummyVektor.addToThis(dummyVektor2);
        dummyLineSegment.copyPoint2(dummyVektor);
        draw(g, dummyLineSegment);
        dummyVektor.setVektor(ra.getReachDist(), Vektor.normalize(ra
            .getBodyDir()
            + ra.getTurn1()
            - 90));
        dummyVektor.addToThis(ra.getCornerPointsBackward()[6]);
        dummyLineSegment.copyPoint1(dummyVektor);
        dummyVektor2.setVektor(ra.getDash1() - ra.getDash2(), Vektor
            .normalize(ra.getBodyDir() + ra.getTurn1()));
        dummyVektor.addToThis(dummyVektor2);
        dummyLineSegment.copyPoint2(dummyVektor);
        draw(g, dummyLineSegment);
        dummyVektor.setVektor(ra.getReachDist(), Vektor.normalize(ra
            .getBodyDir()
            - ra.getTurn1()
            + 90));
        dummyVektor.addToThis(ra.getCornerPointsBackward()[7]);
        dummyLineSegment.copyPoint1(dummyVektor);
        dummyVektor2.setVektor(ra.getDash1() - ra.getDash2(), Vektor
            .normalize(ra.getBodyDir() - ra.getTurn1()));
        dummyVektor.addToThis(dummyVektor2);
        dummyLineSegment.copyPoint2(dummyVektor);
        draw(g, dummyLineSegment);
      }
      else {
        dummyCircle.setCenter(ra.getPos());
        dummyCircle.setRadius(ra.getDash1() + ra.getReachDist());
        draw(g, dummyCircle);
        return;
      }
    }
    if (ra.getDash2() > 0) {
      if (ra.getTurn2() < 90) {
        dummyCircleSegment.copyCenter(ra.getPos());
        dummyCircleSegment.setRadius(ra.getDash2() + ra.getReachDist());
        dummyCircleSegment.setStartAngle(Vektor.normalize(ra.getBodyDir()
            - ra.getTurn2()));
        dummyCircleSegment.setEndAngle(Vektor.normalize(ra.getBodyDir()
            - ra.getTurn1()));
        draw(g, dummyCircleSegment);
        dummyCircleSegment.setStartAngle(Vektor.normalize(ra.getBodyDir()
            + ra.getTurn1()));
        dummyCircleSegment.setEndAngle(Vektor.normalize(ra.getBodyDir()
            + ra.getTurn2()));
        draw(g, dummyCircleSegment);
        dummyCircleSegment.setRadius(ra.getDash2() + ra.getReachDist());
        dummyCircleSegment.setStartAngle(Vektor.normalize(ra.getBodyDir()
            - ra.getTurn2()
            + 180));
        dummyCircleSegment.setEndAngle(Vektor.normalize(ra.getBodyDir()
            - ra.getTurn1()
            + 180));
        draw(g, dummyCircleSegment);
        dummyCircleSegment.setStartAngle(Vektor.normalize(ra.getBodyDir()
            + ra.getTurn1()
            + 180));
        dummyCircleSegment.setEndAngle(Vektor.normalize(ra.getBodyDir()
            + ra.getTurn2()
            + 180));
        draw(g, dummyCircleSegment);

        dummyCircleSegment.setRadius(ra.getReachDist());
        dummyCircleSegment.copyCenter(ra.getCornerPointsBackward()[3]);
        dummyCircleSegment.setStartAngle(Vektor.normalize(ra.getBodyDir()
            + ra.getTurn2()));
        dummyCircleSegment.setEndAngle(Vektor.normalize(ra.getBodyDir()
            + ra.getTurn2()
            + 90));
        draw(g, dummyCircleSegment);
        dummyCircleSegment.copyCenter(ra.getCornerPointsBackward()[4]);
        dummyCircleSegment.setStartAngle(Vektor.normalize(ra.getBodyDir()
            - ra.getTurn2()
            - 90));
        dummyCircleSegment.setEndAngle(Vektor.normalize(ra.getBodyDir()
            - ra.getTurn2()));
        draw(g, dummyCircleSegment);
        dummyCircleSegment.setRadius(ra.getReachDist());
        dummyCircleSegment.copyCenter(ra.getCornerPointsBackward()[8]);
        dummyCircleSegment.setStartAngle(Vektor.normalize(ra.getBodyDir()
            + ra.getTurn2()
            + 180));
        dummyCircleSegment.setEndAngle(Vektor.normalize(ra.getBodyDir()
            + ra.getTurn2()
            - 90));
        draw(g, dummyCircleSegment);
        dummyCircleSegment.copyCenter(ra.getCornerPointsBackward()[9]);
        dummyCircleSegment.setStartAngle(Vektor.normalize(ra.getBodyDir()
            - ra.getTurn2()
            + 90));
        dummyCircleSegment.setEndAngle(Vektor.normalize(ra.getBodyDir()
            - ra.getTurn2()
            + 180));
        draw(g, dummyCircleSegment);

        dummyVektor.setVektor(ra.getReachDist(), Vektor.normalize(ra
            .getBodyDir()
            + ra.getTurn2()
            + 90));
        dummyVektor.addToThis(ra.getCornerPointsBackward()[3]);
        dummyLineSegment.copyPoint1(dummyVektor);
        dummyVektor2.setVektor(ra.getDash2() - ra.getDash3(), Vektor
            .normalize(ra.getBodyDir() + ra.getTurn2() + 180));
        dummyVektor.addToThis(dummyVektor2);
        dummyLineSegment.copyPoint2(dummyVektor);
        draw(g, dummyLineSegment);
        dummyVektor.setVektor(ra.getReachDist(), Vektor.normalize(ra
            .getBodyDir()
            - ra.getTurn2()
            - 90));
        dummyVektor.addToThis(ra.getCornerPointsBackward()[4]);
        dummyLineSegment.copyPoint1(dummyVektor);
        dummyVektor2.setVektor(ra.getDash2() - ra.getDash3(), Vektor
            .normalize(ra.getBodyDir() - ra.getTurn2() + 180));
        dummyVektor.addToThis(dummyVektor2);
        dummyLineSegment.copyPoint2(dummyVektor);
        draw(g, dummyLineSegment);
        dummyVektor.setVektor(ra.getReachDist(), Vektor.normalize(ra
            .getBodyDir()
            + ra.getTurn2()
            - 90));
        dummyVektor.addToThis(ra.getCornerPointsBackward()[8]);
        dummyLineSegment.copyPoint1(dummyVektor);
        dummyVektor2.setVektor(ra.getDash2() - ra.getDash3(), Vektor
            .normalize(ra.getBodyDir() + ra.getTurn2()));
        dummyVektor.addToThis(dummyVektor2);
        dummyLineSegment.copyPoint2(dummyVektor);
        draw(g, dummyLineSegment);
        dummyVektor.setVektor(ra.getReachDist(), Vektor.normalize(ra
            .getBodyDir()
            - ra.getTurn2()
            + 90));
        dummyVektor.addToThis(ra.getCornerPointsBackward()[9]);
        dummyLineSegment.copyPoint1(dummyVektor);
        dummyVektor2.setVektor(ra.getDash2() - ra.getDash3(), Vektor
            .normalize(ra.getBodyDir() - ra.getTurn2()));
        dummyVektor.addToThis(dummyVektor2);
        dummyLineSegment.copyPoint2(dummyVektor);
        draw(g, dummyLineSegment);
      }
      else {
        dummyCircleSegment.copyCenter(ra.getPos());
        dummyCircleSegment.setStartAngle(Vektor.normalize(ra.getBodyDir()
            + ra.getTurn1()));
        dummyCircleSegment.setEndAngle(Vektor.normalize(ra.getBodyDir()
            - ra.getTurn1()
            + 180));
        dummyCircleSegment.setRadius(ra.getDash2() + ra.getReachDist());
        draw(g, dummyCircleSegment);
        dummyCircleSegment.setStartAngle(Vektor.normalize(ra.getBodyDir()
            + ra.getTurn1()
            + 180));
        dummyCircleSegment.setEndAngle(Vektor.normalize(ra.getBodyDir()
            - ra.getTurn1()));
        draw(g, dummyCircleSegment);
        return;
      }
    }
    if (ra.getDash3() > 0) {
      dummyCircleSegment.copyCenter(ra.getPos());
      dummyCircleSegment.setStartAngle(Vektor.normalize(ra.getBodyDir()
          + ra.getTurn2()));
      dummyCircleSegment.setEndAngle(Vektor.normalize(ra.getBodyDir()
          - ra.getTurn2()
          + 180));
      dummyCircleSegment.setRadius(ra.getDash3() + ra.getReachDist());
      draw(g, dummyCircleSegment);
      dummyCircleSegment.setStartAngle(Vektor.normalize(ra.getBodyDir()
          + ra.getTurn2()
          + 180));
      dummyCircleSegment.setEndAngle(Vektor.normalize(ra.getBodyDir()
          - ra.getTurn2()));
      draw(g, dummyCircleSegment);
      return;
    }

  }

  protected void draw(Graphics g,
      LinkedList<Vektor> list) {

    for (Vektor v : list) {
      if (v != null) {
        draw(g, v);
      }
    }
  }

  protected void draw(Graphics g,
      PossibleBallsAfterPoweredAcc possBalls) {
    draw(g, possBalls.getShotCirc());
    if (possBalls.getMaxCirc() != null) {
      draw(g, possBalls.getMaxCirc());
    }
  }

  protected void draw(Graphics g,
      PossibleBallsAfterDirectedAcc possBalls) {
    draw(g,possBalls.getLine());
    if (possBalls.getCirc1()!= null) {
      draw(g,possBalls.getCirc1());
    }
    if (possBalls.getCirc2()!= null) {
      draw(g,possBalls.getCirc2());
    }
  }

  protected void drawKickable(Graphics g,
      Player p) {
    dummyCircle.setCenter(p.getPosition());
    dummyCircle.setRadius(p.getKickDistance());
    draw(g,dummyCircle);
  }

  protected void drawMovement(Graphics g,
      Player p) {
    dummyVektor.copy(p.getSpeed());
    dummyVektor.addToThis(p.getPosition());
    drawArrow(g, p.getPosition().x, p.getPosition().y, dummyVektor.x, dummyVektor.y);
    dummyCircle.setCenter(dummyVektor);
    dummyCircle.setRadius(p.getPConf().PLAYER_SIZE);
    draw(g,dummyCircle);
  }

  protected void drawMovement(Graphics g,
      Ball b) {
    dummyVektor.copy(b.getSpeed());
    dummyVektor.addToThis(b.getPosition());
    drawArrow(g, b.getPosition().x, b.getPosition().y, dummyVektor.x, dummyVektor.y);
    dummyCircle.setCenter(dummyVektor);
    dummyCircle.setRadius(SConf.getInstance().BALL_SIZE);
    draw(g,dummyCircle);
  }

  protected void drawOppPenalty(Graphics g) {
    dummyVektor.x= -SConf.getInstance().half_width;
    dummyVektor.y= SConf.getInstance().half_length;
    dummyLineSegment.copyPoint1(dummyVektor);
    dummyVektor.x= SConf.getInstance().half_width;
    dummyLineSegment.copyPoint2(dummyVektor);
    draw(g, dummyLineSegment);
    dummyVektor.x= -SConf.getInstance().half_penalty_width;
    dummyVektor.y= SConf.getInstance().half_length;
    dummyLineSegment.copyPoint1(dummyVektor);
    dummyVektor.y= SConf.getInstance().half_length-SConf.getInstance().half_penalty_width;
    dummyLineSegment.copyPoint2(dummyVektor);
    draw(g, dummyLineSegment);
    dummyVektor.x= SConf.getInstance().half_penalty_width;
    dummyVektor.y= SConf.getInstance().half_length;
    dummyLineSegment.copyPoint1(dummyVektor);
    dummyVektor.y= SConf.getInstance().half_length-SConf.getInstance().half_penalty_width;
    dummyLineSegment.copyPoint2(dummyVektor);
    draw(g, dummyLineSegment);
    dummyVektor.x= -SConf.getInstance().half_penalty_width;
    dummyLineSegment.copyPoint1(dummyVektor);
    draw(g, dummyLineSegment);
    dummyVektor.x= 0;
    dummyVektor.y= SConf.getInstance().half_length-11;
    dummyCircle.setCenter(dummyVektor);
    dummyCircle.setRadius(0.1);
    fill(g, dummyCircle);
    dummyVektor.x= -SConf.getInstance().half_goal_width;
    dummyVektor.y= SConf.getInstance().half_length;
    dummyLineSegment.copyPoint1(dummyVektor);
    dummyVektor.y= SConf.getInstance().half_length+2.5;
    dummyLineSegment.copyPoint2(dummyVektor);
    draw(g, dummyLineSegment);
    dummyVektor.x= SConf.getInstance().half_goal_width;
    dummyVektor.y= SConf.getInstance().half_length;
    dummyLineSegment.copyPoint1(dummyVektor);
    dummyVektor.y= SConf.getInstance().half_length+2.5;
    dummyLineSegment.copyPoint2(dummyVektor);
    draw(g, dummyLineSegment);
    dummyVektor.x= -SConf.getInstance().half_goal_width;
    dummyLineSegment.copyPoint1(dummyVektor);
    draw(g, dummyLineSegment);
  }

  protected void draw(Graphics g,
      ShotEvaluatorResults results, Ball b) {
    dummyCircleSegment.copyCenter(b.getPosition());
    dummyCircleSegment.setRadius(30);
    for (int i= 0; i < results.getAreas(); i++) {
      if (results.getShotValue(i) == SHOT_VALUE.IN) {
        g.setColor(transparentGreen);
      }
      else if (results.getShotValue(i) == SHOT_VALUE.MISS_OUT) {
        g.setColor(transparentRed);
      }
      else if (results.getShotValue(i) == SHOT_VALUE.MISS_OPP) {
        g.setColor(transparentBrown);
      }
      else {
        g.setColor(transparentBlue);
      }      
      dummyCircleSegment.setStartAngle(results.getStartAngle(i));
      dummyCircleSegment.setEndAngle(results.getEndAngle(i));
      fill(g,dummyCircleSegment);
    }
  }

}
